import pygame
from pygame import Surface
from abc import abstractmethod, ABC
from .utils import get_direction


class Animal(ABC, pygame.sprite.Sprite):
    INIT_POSITION_X: int
    INIT_POSITION_Y: int
    FRAME_SPEED: float
    MOVE_SPEED: float
    SCORE: int
    DEATH_ANIMATION_FRAMES = 2  # 新增死亡动画帧数属性
    DEATH_FRAME_SPEED = 0.2     # 新增死亡动画播放速度

    def __init__(self):
        super().__init__()
        self.snake_pos = pygame.Vector2(self.INIT_POSITION_X, self.INIT_POSITION_Y)
        self.frame_index = 0
        
        self.pics = self.get_pics()
        self.image = self.move(self.pics)
        self.rect = self.image.get_rect(topleft=self.snake_pos)

        self.is_dead = False  # 新增死亡状态标识
        self.death_pics = self.get_death_pics()  # 新增死亡动画图片
        self.death_frame_index = 0  # 新增死亡动画帧索引

    @abstractmethod
    def get_pics(self) -> list[Surface]:
        # 获取动画的图片
        ...

    @abstractmethod
    def get_death_pics(self) -> list[Surface]:  # 新增死亡动画抽象方法
        ...

    def update(self, play_pos: tuple[int, int]) -> None:
        if self.is_dead:
            # 死亡动画逻辑
            self.death_frame_index += self.DEATH_FRAME_SPEED            
            if self.death_frame_index >= self.DEATH_ANIMATION_FRAMES:
                self.kill()
            else:
                self.image = self.death_pics[int(self.death_frame_index)]
            return

        # 原有移动逻辑保持不变
        self.image = self.move(self.pics)
        direction = get_direction(play_pos, self.rect.center)
        self.rect.x += direction[0] * self.MOVE_SPEED  # x轴方向向玩家移动
        if isinstance(self, (Bat, Fly, Bee)):  # isinstance()是python内置方法，用来判断一个类是否属于某个类或者某些类之一
            if self.get_distance_to_player(play_pos) < 500:
                # 如果距离小于500，则向玩家移动
                self.rect.y += direction[1] * self.MOVE_SPEED   # y轴方向向玩家移动         
        if self.rect.x < 0:
            # 如果超出屏幕，则使用sprite.kill()方法删除该精灵
            self.kill()

    def get_distance_to_player(self, player_pos: tuple[int, int]) -> float:
        '''
        参数：
            player_pos: tuple[int, int] 玩家位置
        返回值：  
            float: 玩家与敌人之间的距离
        '''
        player_vec = pygame.Vector2(player_pos)
        enemy_vec = pygame.Vector2(self.rect.center)
        distance = player_vec.distance_to(enemy_vec)
        return distance

    def move(self, pics: list[Surface]) -> Surface:
        '''
        获取当前播放的帧  
        参数：  
            pics: list[Surface] 帧列表
        返回值：  
            Surface: 当前播放的帧
        '''
        self.frame_index += self.FRAME_SPEED
        if self.frame_index >= 2:
            self.frame_index = 0

        return pics[int(self.frame_index)]

    def die(self):  # 新增死亡方法
        self.is_dead = True        
        self.image = self.death_pics[0]

class Snake(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 600
    FRAME_SPEED = 0.4
    MOVE_SPEED = 4
    SCORE = 100
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/snake.png"),
            pygame.image.load("pics/enemies/snake_walk.png")
        ]
        return pics

    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/snake_death1.png"),
            pygame.image.load("pics/enemies/snake_death2.png")
        ]

class Frog(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 600
    FRAME_SPEED = 0.1
    MOVE_SPEED = 3
    SCORE = 80
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/frog.png"),
            pygame.image.load("pics/enemies/frog_leap.png")
        ]
        return pics

    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/frog_death1.png"),
            pygame.image.load("pics/enemies/frog_death2.png")
        ]

class Snail(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 600
    FRAME_SPEED = 0.2
    MOVE_SPEED = 1
    SCORE = 50
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/snail.png"),
            pygame.image.load("pics/enemies/snail_walk.png")
        ]
        return pics
    
    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/snail_death1.png"),
            pygame.image.load("pics/enemies/snail_death2.png")
        ]

class LadyBug(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 600
    FRAME_SPEED = 0.4
    MOVE_SPEED = 6
    SCORE = 120
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/ladybug.png"),
            pygame.image.load("pics/enemies/ladybug_walk.png")
        ]
        return pics
    
    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/ladybug_death1.png"),
            pygame.image.load("pics/enemies/ladybug_death2.png")
        ]

class Bee(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 400
    FRAME_SPEED = 0.5
    MOVE_SPEED = 8
    SCORE = 150
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/bee.png"),
            pygame.image.load("pics/enemies/bee_fly.png")
        ]
        return pics
    
    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/bee_death1.png"),
            pygame.image.load("pics/enemies/bee_death2.png")
        ]

class Bat(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 200
    FRAME_SPEED = 0.5
    MOVE_SPEED = 6
    SCORE = 120
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/bat.png"),
            pygame.image.load("pics/enemies/bat_fly.png")
        ]
        return pics
    
    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/bat_death1.png"),
            pygame.image.load("pics/enemies/bat_death2.png")
        ]

class Fly(Animal):
    INIT_POSITION_X = 900
    INIT_POSITION_Y = 500
    FRAME_SPEED = 0.5
    MOVE_SPEED = 10
    SCORE = 160
    def get_pics(self) -> list[Surface]:
        pics = [
            pygame.image.load("pics/enemies/fly.png"),
            pygame.image.load("pics/enemies/fly_fly.png")
        ]
        return pics
    
    def get_death_pics(self) -> list[Surface]:
        return [
            pygame.image.load("pics/enemies/fly_death1.png"),
            pygame.image.load("pics/enemies/fly_death2.png")
        ]
